/*
* Sun Public License Notice
*
* The contents of this file are subject to the Sun Public License
* Version 1.0 (the "License"). You may not use this file except in
* compliance with the License. A copy of the License is available at
* http://www.sun.com/
*
* The Original Code is Forte for Java, Community Edition. The Initial
* Developer of the Original Code is Sun Microsystems, Inc. Portions
* Copyright 1997-2000 Sun Microsystems, Inc. All Rights Reserved.
*/
package org.openide.explorer.propertysheet.editors;
import java.awt.event.*;
import java.beans.PropertyChangeSupport;
import java.lang.reflect.Modifier;
import java.util.StringTokenizer;
import java.util.ResourceBundle;
import javax.swing.*;
import org.openide.util.NbBundle;
/** JPanel extension containing components which allows visual
* editing Modifier object.
* This class has two main properties: mask (possible values mask)
* and modifier (current value).
*
* @author Petr Hamernik
*/
class ModifierPanel extends javax.swing.JPanel {
// ------------------------- Statics -------------------------------
/** Resource bundle. */
static final ResourceBundle bundle = NbBundle.getBundle(ModifierPanel.class);
/** Name of 'mask' property */
public static final String PROP_MASK = "mask"; // NOI18N
/** Name of 'modifier' property (current value) */
public static final String PROP_MODIFIER = "modifier"; // NOI18N
/** Names of modifiers */
private static final String MODIFIER_NAMES[] = {
"abstract", "final", "static", "synchronized", "transient", "volatile", "native" // NOI18N
};
/** Values of modifiers */
private static final int MODIFIER_VALUES[] = {
Modifier.ABSTRACT, Modifier.FINAL, Modifier.STATIC, Modifier.SYNCHRONIZED,
Modifier.TRANSIENT, Modifier.VOLATILE, Modifier.NATIVE
};
/** Count of the modifiers */
private static final int MODIFIER_COUNT = MODIFIER_VALUES.length;
/** Names of accessibility */
private static final String ACCESS_NAMES[] = {
"<default>", "private", "protected", "public" // NOI18N
};
/** Values of accessibility */
private static final int ACCESS_VALUES[] = {
0, Modifier.PRIVATE, Modifier.PROTECTED, Modifier.PUBLIC
};
/** Mask of access modifiers */
private static final int ACCESS_MASK = Modifier.PRIVATE | Modifier.PROTECTED | Modifier.PUBLIC;
/** Mask of all possible modifiers. */
static final int EDITABLE_MASK = ACCESS_MASK | Modifier.ABSTRACT |
Modifier.FINAL | Modifier.STATIC | Modifier.SYNCHRONIZED |
Modifier.TRANSIENT | Modifier.VOLATILE | Modifier.NATIVE;
// ------------------ Instance Fields --------------------------
/** Current mask */
private int mask;
/** Current value */
private int modifier;
/** Current access values shown in the combo box */
private int currentAccessValues[];
/** Current access names shown in the combo box */
private String currentAccessNames[];
/** JCheckBox array */
private JCheckBox[] checks;
/** listener for visual changes */
private ActionListener listener;
/** Ignored flag - used during firing change events */
private boolean ignored = false;
/** Property support for changes in the ModifiersPanel bean */
private PropertyChangeSupport propertyChangeSupport;
static final long serialVersionUID =6884758007403225916L;
/** Creates new form ModifiersPanel */
public ModifierPanel() {
mask = EDITABLE_MASK;
modifier = 0;
currentAccessValues = ACCESS_VALUES;
currentAccessNames = ACCESS_NAMES;
listener = new ActionListener() {
public void actionPerformed(ActionEvent evt) {
if ((checks[0].isSelected()) && ((modifier & MODIFIER_VALUES[0]) == 0))
checks[1].setSelected(false);
if ((checks[1].isSelected()) && ((modifier & MODIFIER_VALUES[1]) == 0))
checks[0].setSelected(false);
if (!ignored)
updateValue();
}
};
ignored = true;
initComponents();
modifPanel.setBorder (new javax.swing.border.CompoundBorder(
new javax.swing.border.TitledBorder(bundle.getString("LAB_Modifiers")),
new javax.swing.border.EmptyBorder(new java.awt.Insets(3, 3, 3, 3))
));
propertyChangeSupport = new PropertyChangeSupport(this);
updateAccess();
updateModifiers();
updateComponents();
ignored = false;
}
/** This method is called from within the constructor to
* initialize the form.
* WARNING: Do NOT modify this code. The content of this method is
* always regenerated by the FormEditor.
*/
private void initComponents () {//GEN-BEGIN:initComponents
modifPanel = new javax.swing.JPanel ();
jPanel2 = new javax.swing.JPanel ();
jLabel1 = new javax.swing.JLabel ();
accessCombo = new javax.swing.JComboBox ();
setLayout (new java.awt.BorderLayout ());
setBorder (new javax.swing.border.EmptyBorder(new java.awt.Insets(6, 7, 6, 7)));
modifPanel.setLayout (new java.awt.GridLayout (4, 2, 4, 4));
checks = new JCheckBox[MODIFIER_COUNT];
for (int i = 0; i < MODIFIER_COUNT; i++) {
checks[i] = new JCheckBox(MODIFIER_NAMES[i]);
modifPanel.add(checks[i]);
checks[i].setEnabled((this.mask & MODIFIER_VALUES[i]) != 0);
checks[i].addActionListener(listener);
}
add (modifPanel, java.awt.BorderLayout.CENTER);
jPanel2.setLayout (new java.awt.BorderLayout (8, 8));
jPanel2.setBorder (new javax.swing.border.EmptyBorder(new java.awt.Insets(5, 5, 5, 5)));
jLabel1.setText (bundle.getString("LAB_AccessRights"));
jPanel2.add (jLabel1, java.awt.BorderLayout.WEST);
accessCombo.addActionListener(listener);
jPanel2.add (accessCombo, java.awt.BorderLayout.CENTER);
add (jPanel2, java.awt.BorderLayout.NORTH);
}//GEN-END:initComponents
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JPanel modifPanel;
private javax.swing.JPanel jPanel2;
private javax.swing.JLabel jLabel1;
private javax.swing.JComboBox accessCombo;
// End of variables declaration//GEN-END:variables
/** Add a PropertyChangeListener to the listener list.
*@param l The listener to add.
*/
public void addPropertyChangeListener(java.beans.PropertyChangeListener l) {
propertyChangeSupport.addPropertyChangeListener (l);
}
/** Removes a PropertyChangeListener from the listener list.
*@param l The listener to remove.
*/
public void removePropertyChangeListener(java.beans.PropertyChangeListener l) {
propertyChangeSupport.removePropertyChangeListener (l);
}
/** Getter for property mask.
*@return Value of property mask.
*/
public int getMask() {
return mask;
}
/** Setter for property mask.
*@param mask New value of property mask.
*/
public void setMask(int mask) {
if (this.mask != mask) {
int oldMask = this.mask;
this.mask = mask & EDITABLE_MASK;
updateAccess();
updateModifiers();
propertyChangeSupport.firePropertyChange (PROP_MASK, new Integer (oldMask), new Integer (mask));
setModifier(modifier & mask);
}
}
/** Update access ComboBox values depending on new 'mask' property
*/
private void updateAccess() {
int selValue = modifier & ACCESS_MASK;
int selIndex = 0;
int counter = 1;
for (int i = 1; i < ACCESS_VALUES.length; i++) {
if ((ACCESS_VALUES[i] & mask) != 0)
counter++;
}
currentAccessValues = new int[counter];
currentAccessNames = new String[counter];
currentAccessValues[0] = ACCESS_VALUES[0];
currentAccessNames[0] = ACCESS_NAMES[0];
counter = 1;
for (int i = 1; i < ACCESS_VALUES.length; i++) {
if ((ACCESS_VALUES[i] & mask) != 0) {
currentAccessValues[counter] = ACCESS_VALUES[i];
currentAccessNames[counter] = ACCESS_NAMES[i];
if (ACCESS_VALUES[i] == selValue) {
selIndex = counter;
}
counter++;
}
}
ignored = true;
accessCombo.setModel(new DefaultComboBoxModel(currentAccessNames));
accessCombo.setSelectedIndex(selIndex);
ignored = false;
}
/** Update enable status of all modifiers check boxes
*/
private void updateModifiers() {
for (int i = 0; i < MODIFIER_COUNT; i++) {
checks[i].setEnabled((mask & MODIFIER_VALUES[i]) != 0);
}
}
/** Getter for property modifier.
*@return Value of property modifier.
*/
public int getModifier() {
return modifier;
}
/** Setter for property modifier.
*@param modifier New value of property modifier.
*/
public void setModifier(int modifier) {
if (this.modifier != modifier) {
boolean accessUsed = false;
for (int i = 1; i < ACCESS_VALUES.length; i++) {
if ((ACCESS_VALUES[i] & modifier) != 0) {
if (accessUsed)
throw new IllegalArgumentException();
else
accessUsed = true;
}
}
int oldModifier = this.modifier;
this.modifier = modifier;
ignored = true;
updateComponents();
ignored = false;
propertyChangeSupport.firePropertyChange (PROP_MODIFIER, new Integer (oldModifier), new Integer (modifier));
}
}
/** Update the components inside the ModifierPanel depending on new value
* of 'modifier' property.
*/
private void updateComponents() {
int selIndex = 0;
for (int i = 1; i < currentAccessValues.length; i++) {
if ((currentAccessValues[i] & modifier) != 0) {
selIndex = i;
break;
}
}
accessCombo.setSelectedIndex(selIndex);
for (int i = 0; i < MODIFIER_COUNT; i++) {
checks[i].setSelected((modifier & MODIFIER_VALUES[i]) != 0);
}
}
/** Updates the value depending on the status of the components. */
private void updateValue() {
int newValue = 0;
newValue |= currentAccessValues[accessCombo.getSelectedIndex()];
for (int i = 0; i < MODIFIER_COUNT; i++) {
if (checks[i].isSelected() & checks[i].isEnabled())
newValue |= MODIFIER_VALUES[i];
}
if (modifier != newValue) {
int oldValue = modifier;
modifier = newValue;
propertyChangeSupport.firePropertyChange(PROP_MODIFIER,
new Integer(oldValue), new Integer(modifier));
}
}
/** Sets the 'modifier' property as a text.
* @param string The text form of modifier like 'public static final'
* Optionally delimited by comma.
* @exception IllegalArgumentException if parameter cannot be parsed.
*/
public void setText(String string) throws IllegalArgumentException {
int newValue = 0;
int oldValue = modifier;
StringTokenizer tukac = new StringTokenizer(string, ", ", false); // NOI18N
while (tukac.hasMoreTokens()) {
String token = tukac.nextToken();
boolean known = false;
for (int i = 0; i < MODIFIER_COUNT; i++) {
if ((MODIFIER_VALUES[i] & mask) != 0) {
if (token.equals(MODIFIER_NAMES[i])) {
if (((MODIFIER_VALUES[i] == Modifier.FINAL) && ((newValue & Modifier.ABSTRACT) != 0)) ||
((MODIFIER_VALUES[i] == Modifier.ABSTRACT) && ((newValue & Modifier.FINAL) != 0)))
break;
newValue |= MODIFIER_VALUES[i];
known = true;
break;
}
}
}
if ((newValue & ACCESS_MASK) == 0) {
for (int i = 1; i <= 3; i++) {
if ((ACCESS_VALUES[i] & mask) != 0) {
if (token.equals(ACCESS_NAMES[i])) {
newValue |= ACCESS_VALUES[i];
known = true;
break;
}
}
}
}
if (!known)
throw new IllegalArgumentException();
}
if (oldValue != newValue) {
modifier = newValue;
ignored = true;
updateComponents();
ignored = false;
propertyChangeSupport.firePropertyChange(PROP_MODIFIER,
new Integer(oldValue), new Integer(modifier));
}
}
}